This makes it easier to maintain the code and to avoid memory leaks.
 static GList *load(const char *file);
 static gboolean bookmark_contains_all_tags(Bookmark *bm, char **query,
     unsigned int qlen);
-static Bookmark *line_to_bookmark(char *uri, char *data);
+static Bookmark *line_to_bookmark(const char *uri, const char *data);
 static void free_bookmark(Bookmark *bm);
 
 /**
     return true;
 }
 
-static Bookmark *line_to_bookmark(char *uri, char *data)
+static Bookmark *line_to_bookmark(const char *uri, const char *data)
 {
     char *p;
     Bookmark *bm;
 
     /* data part may consist of title or title<tab>tags*/
     bm      = g_slice_new(Bookmark);
-    bm->uri = uri;
+    bm->uri = g_strdup(uri);
     if ((p = strchr(data, '\t'))) {
         *p        = '\0';
-        bm->title = data;
-        bm->tags  = p + 1;
+        bm->title = g_strdup(data);
+        bm->tags  = g_strdup(p + 1);
     } else {
-        bm->title = data;
+        bm->title = g_strdup(data);
         bm->tags  = NULL;
     }
 
 static void free_bookmark(Bookmark *bm)
 {
     g_free(bm->uri);
+    g_free(bm->title);
+    g_free(bm->tags);
     g_slice_free(Bookmark, bm);
 }
 
 static void write_to_file(GList *list, const char *file);
 static gboolean history_item_contains_all_tags(History *item, char **query,
     unsigned int qlen);
-static History *line_to_history(char *uri, char *title);
+static History *line_to_history(const char *uri, const char *title);
 static void free_history(History *item);
 
 
     return true;
 }
 
-static History *line_to_history(char *uri, char *title)
+static History *line_to_history(const char *uri, const char *title)
 {
     History *item = g_slice_new0(History);
 
-    item->first  = uri;
-    item->second = title;
+    item->first  = g_strdup(uri);
+    item->second = g_strdup(title);
 
     return item;
 }
 
 static void free_history(History *item)
 {
-    /* The first and second property are created from the same allocated
-     * string so we only need to free the first. */
     g_free(item->first);
+    g_free(item->second);
     g_slice_free(History, item);
 }
 
  * line.
  *
  * @filename:    file to read items from
- * @func:        Function to parse a single line to item. This is called by
- *               two strings of the same allocated memory chunk which isn't
- *               freed here. This allows to use the strings like they are. But
- *               in case the memory should be freed, free only that of the
- *               first string.
+ * @func:        Function to parse a single line to item.
  * @max_items:   maximum number of items that are returned, use 0 for
  *               unlimited items
  */
         line = lines[i];
         g_strstrip(line);
         if (!*line) {
-            g_free(lines[i]);
             continue;
         }
 
         /* If the item is already in the has table we don't ned to put it in
          * the list, but we have to free the momory. */
         if (g_hash_table_lookup_extended(ht, key, NULL, NULL)) {
-            g_free(lines[i]);
             continue;
         }
 
 
             /* Don't put more entries into the list than requested. */
             if (max_items && g_hash_table_size(ht) >= max_items) {
-                /* Free all following lines that are not put into the list. */
-                while(--i >= 0) {
-                    g_free(lines[i]);
-                }
                 break;
             }
         }
     }
 
-    /* Free the memory for the string array but keep the strings untouched. */
-    g_free(lines);
+    g_strfreev(lines);
     g_hash_table_destroy(ht);
 
     return gl;
 
     UTIL_EXP_SPECIAL = 0x04, /* expand % to current URI */
 };
 
-typedef void *(*Util_Content_Func)(char*, char*);
+typedef void *(*Util_Content_Func)(const char*, const char*);
 
 char* util_get_config_dir(void);
 char* util_get_cache_dir(void);